local class = reload("class")
local super = reload("super.basic")
local timer = reload("single.timer")
local midws = reload("global.midws")

local state = {
    wait = 1, ---待开启
    runt = 2, ---运行时
    calc = 3, ---结算中
    view = 4, ---展示中
    dele = 5, ---已删除
}

local function totalsec(cfg)
    return cfg.runSec + cfg.calcSec + cfg.viewSec
end

---@class temporary @期限功能
local this = class(super)

function this:ctor()
    super.ctor(self)
    return self
end

function this:clear()
    super.clear()
end

function this:launch(cfg)
    this:async(self.load, {
        cfg = cfg,
        map = {}, --活动信息
        obj = {}, --活动实例
    })
    return self
end

function this:load(arg)
    ---获取自增表示
    local rinfo = midws.rdb._info
    local key = string.format("global:hash:%d:data", rinfo.zone)
    arg.globalHashDataKey = key
    midws.rdb:hget(key, "temporaryid")(self.coback, self, arg)
    local tid = self:await()
    arg.tid = tonumber(tid) or 1

    ---获取活动对象{[id] = pbTemporaryInfo}
    key = string.format("global:hash:%d:temporary", rinfo.zone)
    arg.globalHashTemporaryKey = key
    midws.rdb:hgetall(key)(self.coback, self, arg)
    local hash = self:await()
    for sid, str in pairs(hash) do
        local objid = tonumber(sid)
        local info = midws.lpb:decode("pbTemporaryInfo", str)
        arg.map[objid] = info
    end

    self._arg = arg
    ---实例化活动对象
    for _, info in pairs(arg.map) do
        ---实例化活动对象
        self:create(info)
    end

    if not next(arg.map) then
        local nowsec = timer:nowsec()
        self:append("测试活动", 1, nowsec)
    end
end

function this:append(name, cfgid, start)
    ---实例化标识
    local arg = self._arg
    local tid = arg.tid
    arg.tid = tid + 1

    ---活动配置
    local cfg = arg.cfg[cfgid]
    if not cfg then
        return
    end

    local info = {
        name  = name,
        start = start,
        state = state.runt,
        objid = tid,
        cfgid = cfgid,
        count = 1
    }

    ---实例化活动对象
    self:create(info)

    self:refresh(info)
    return true
end

---刷新活动
function this:refresh(info)
    local arg = self._arg
    ---活动入库
    local pack = midws.lpb:encode("pbTemporaryInfo", info)
    midws.rdb:hset(arg.globalHashTemporaryKey, info.objid, pack)
end

---删除活动
function this:delete(objid)
    local arg = self._arg
    arg.map[objid] = nil
    arg.obj[objid] = nil
    midws.rdb:hdel(arg.globalHashTemporaryKey, objid)
end

function this:create(info)
    local arg = self._arg
    local cfg = arg.cfg[info.cfgid]
    ---实例化活动对象
    local obj = reload(cfg.class).new(info)
    arg.obj[info.objid] = obj
    arg.map[info.objid] = info
    self:nextState(obj, info)
end

function this:nextState(obj, info)
    local arg = self._arg
    local cfg = arg.cfg[info.cfgid]
    local now = timer:nowsec()
    if state.wait == info.state then
        ---计算运行回调
        local sec = info.start
        local ms = (sec - now) * 1000
        timer:appendCall(ms, self.stateCallback, self, obj, info)
    elseif state.runt == info.state then
        ---计算结算回调
        local sec = info.start + cfg.runSec
        local ms = (sec - now) * 1000
        timer:appendCall(ms, self.stateCallback, self, obj, info)
    elseif state.calc == info.state then
        ---计算展示回调
        local sec = info.start + cfg.runSec + cfg.calcSec
        local ms = (sec - now) * 1000
        timer:appendCall(ms, self.stateCallback, self, obj, info)
    elseif state.view == info.state then
        ---计算删除回调
        local sec = info.start + cfg.runSec + cfg.calcSec + cfg.viewSec
        local ms = (sec - now) * 1000
        timer:appendCall(ms, self.stateCallback, self, obj, info)
    elseif state.dele == info.state then
        ---计算删除之后
        local sec = info.start + totalsec(cfg)
        local ms = (sec - now) * 1000
        timer:appendCall(ms, self.stateCallback, self, obj, info)
    end
end

---状态回调
function this:stateCallback(obj, info)
    local arg = self._arg
    local cfg = arg.cfg[info.cfgid]
    info.state = info.state + 1
    if state.runt == info.state then
        ---运行状态
        obj:stateRun()
        ---下次状态
        self:nextState(obj, info)
    elseif state.calc == info.state then
        ---结算状态
        obj:stateCalc()
        ---下次状态
        self:nextState(obj, info)
    elseif state.view == info.state then
        ---展示状态
        obj:stateView()
        ---下次状态
        self:nextState(obj, info)
    elseif state.dele == info.state then
        obj:stateDele()

        ---删除活动
        if cfg.count >= info.count then
            if not cfg.forever then
                self:delete()
                return
            end
        end

        ---活动重置
        info.count = info.count + 1
        info.state = state.wait
        info.start = info.start + totalsec(cfg)
        obj:resetProc()

        ---下次状态
        self:nextState(obj, info)
    end

    self:refresh(info)
end

return this

--[[
    global:hash:zone:data = {
        ["temporaryid"] = number 自增标识
    }

    global:hash:zone:temporary = {
        [temporaryid] = { pbTemporaryInfo
            name        =   string   --活动名称
            start       =   number;  --开始时间
            state       =   number;  --1活动状态 2结算状态 3展示状态 4结束状态
            objid       =   number;  --活动标识-数据管理
            class       =   number;  --活动类型-配置标识
            count       =   number;  --活动次数
        }
    }

    temporarycfg = { ---全局活动配置
        [temporaryid] = { ---临时活动配置
            class   = string    活动对象 比如: chargeFirst
            runSec  = number    运行秒数
            calcSec = number    结算秒数
            viewSec = number    展示秒数
            forever = boolean   永久活动
            count   = number    活动次数
        },
    }
]]
